﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using WiimoteLib;

namespace WiiHub {
    //TODO: WiiHub should be changed to use WCF but
    // - I wrote this under pressure in a hotel with no internet access
    //   and in a very close deadline
    // - UDP probably allows easier integration with non .NET apps
    // - Creates other issues though, its a one way stream. No way to set
    //   rumble or lights currently.
    public partial class MainWindow : Window {
        Socket mSocket;
        IPEndPoint mEndPoint;

        Wiimote mWiimote;
        DispatcherTimer mWiiTimer = new DispatcherTimer();

        public MainWindow () {
            InitializeComponent();
            Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing);
            butnStart.Click += new RoutedEventHandler(butnStart_Click);
            butnTest.Click += new RoutedEventHandler(butnTest_Click);
        }

        void Stop () {
            if (mWiimote != null) {
                mWiimote.Disconnect();
                mWiimote.Dispose();
                mWiimote = null;
            }
        }

        void MainWindow_Closing (object sender, System.ComponentModel.CancelEventArgs e) {
            Stop();
        }

        void butnTest_Click (object sender, RoutedEventArgs e) {
            var xBytes = new byte[(int)RecordIndex.Size];
            xBytes[(int)RecordIndex.DDown] = 1;
            mSocket.SendTo(xBytes, mEndPoint);
        }

        void butnStart_Click (object sender, RoutedEventArgs e) {
            try {
                mWiimote = new Wiimote();
                mWiimote.Connect();
                mWiimote.SetReportType(Wiimote.InputReport.ButtonsAccel, true);
                lablWiimoteStatus.Content = "Wiimote is connected.";

                mWiiTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000 / 60);
                mWiiTimer.Tick += new EventHandler(mWiiTimer_Tick);
                mWiiTimer.Start();
            } catch {
                mWiimote = null;
            }

            mSocket = new Socket(AddressFamily.InterNetwork
                , SocketType.Dgram, ProtocolType.Udp);
            mSocket.EnableBroadcast = true;
            var xIP = chckUseLoopback.IsChecked.Value ? IPAddress.Loopback : IPAddress.Broadcast;
            mEndPoint = new IPEndPoint(xIP, Global.DefaultPort);
        }

        void mWiiTimer_Tick (object sender, EventArgs e) {
            byte[] xBytes = new byte[(int)RecordIndex.Size];
            var xState = mWiimote.WiimoteState;

            xBytes[(int)RecordIndex.A] = (byte)(xState.ButtonState.A ? 1 : 0);
            xBytes[(int)RecordIndex.B] = (byte)(xState.ButtonState.B ? 1 : 0);
            xBytes[(int)RecordIndex.DDown] = (byte)(xState.ButtonState.Down ? 1 : 0);
            xBytes[(int)RecordIndex.DLeft] = (byte)(xState.ButtonState.Left ? 1 : 0);
            xBytes[(int)RecordIndex.DRight] = (byte)(xState.ButtonState.Right ? 1 : 0);
            xBytes[(int)RecordIndex.DUp] = (byte)(xState.ButtonState.Up ? 1 : 0);
            xBytes[(int)RecordIndex.Home] = (byte)(xState.ButtonState.Home ? 1 : 0);
            xBytes[(int)RecordIndex.Minus] = (byte)(xState.ButtonState.Minus ? 1 : 0);
            xBytes[(int)RecordIndex.Plus] = (byte)(xState.ButtonState.Plus ? 1 : 0);
            xBytes[(int)RecordIndex.One] = (byte)(xState.ButtonState.One ? 1 : 0);
            xBytes[(int)RecordIndex.Two] = (byte)(xState.ButtonState.Two ? 1 : 0);

            mSocket.SendTo(xBytes, mEndPoint);
        }

    }
}
